//package com.lcn.db.relational;
//
//import com.lcn.comm.domain.TxTransactionLocal;
//import com.lcn.comm.framework.task.TxTask;
//import com.lcn.comm.service.db.CallClose;
//import com.lcn.comm.service.db.DataSourceService;
//import com.lcn.comm.service.db.LCNConnection;
//import com.lcn.comm.service.db.LCNDataSource;
//import com.weibo.api.motan.config.springsupport.annotation.MotanReferer;
//import com.weibo.api.motan.util.LoggerUtil;
//
//import javax.annotation.Resource;
//import javax.sql.DataSource;
//import java.io.PrintWriter;
//import java.sql.Connection;
//import java.sql.SQLException;
//import java.sql.SQLFeatureNotSupportedException;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.logging.Logger;
//
///**
// * <p>类说明</p>
// *
// * @author 张峰 zfvip_it@163.com
// * @create: 2017-12-25 10:45
// */
//public abstract class AbstractDataSource<T> implements DataSource, LCNDataSource {
//
//    protected Map<String, LCNConnection> pools = new ConcurrentHashMap<>();
//
//    @MotanReferer
//    protected DataSourceService dataSourceService;
//
//    /**
//     * 最大连接数，默认5
//     */
//    protected volatile int maxCount = 5;
//
//    /**
//     * 当前连接数
//     */
//    protected volatile int nowCount = 0;
//
//    /**
//     * 获取连接最长等待时间(秒)
//     */
//    protected int requestTimeOut = 30;
//
//    /**
//     * 数据源对象
//     */
//    protected DataSource dataSource;
//
//    /**
//     * 加载连接池对象
//     *
//     * @return
//     */
//    protected LCNConnection loadConnection() {
//        TxTransactionLocal txTransactionLocal = TxTransactionLocal.current();
//        if (txTransactionLocal != null) {
//            LCNConnection oldConnection = pools.get(txTransactionLocal.getGroupId());
//            if (oldConnection != null) {
//                if (txTransactionLocal.isHasConnection()) {
//                    LoggerUtil.info("连接已完成，事务将从新获取连接");
//                    return null;
//                }
//                LoggerUtil.info("存在旧的连接池，返回之前的连接池");
//                txTransactionLocal.setHasConnection(true);
//                return oldConnection;
//            }
//        } else {
//            LoggerUtil.info("当前线程本地事务对象为空");
//        }
//        return null;
//    }
//
//    /**
//     * 初始化连接池
//     *
//     * @param connection
//     * @return
//     */
//    protected T initLCNConnection(T connection) {
//        TxTransactionLocal txTransactionLocal = TxTransactionLocal.current();
//        if (txTransactionLocal != null && !txTransactionLocal.isHasConnection()) {
//            //重新创建代理连接
//            T t = createConnection(txTransactionLocal, connection);
//            return t;
//        }
//        return connection;
//    }
//
//    /**
//     * 创建代理连接
//     *
//     * @param txTransactionLocal
//     * @param connection
//     */
//    private T createConnection(TxTransactionLocal txTransactionLocal, T connection) {
//        if (nowCount == maxCount) {//等待获取连接
//            for (int i = 0; i < requestTimeOut; i++) {
//                for (int j = 0; j < 100; j++) {
//                    try {
//                        Thread.sleep(10);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    if (nowCount < maxCount) {
//                        return createLcnConnection(connection, txTransactionLocal);
//                    }
//                }
//            }
//        } else if (nowCount < maxCount) {
//            return createLcnConnection(connection, txTransactionLocal);
//        } else {
//            LoggerUtil.info("数据库连接池超过限制");
//        }
//        return connection;
//    }
//
//    /**
//     * 关闭连接池
//     */
//    protected CallClose subNowCount = new CallClose() {
//
//        public void close(LCNConnection lcnConnection) {
//            TxTask txTask = lcnConnection.getWaitTask();
//            if (txTask != null) {
//                LoggerUtil.info("关闭数据库连接,groupId[{}]", txTask.getGroupId());
//                if (!txTask.isRemove()) {
//                    txTask.remove();
//                }
//            }
//            pools.remove(lcnConnection.getGroupId());
//            nowCount--;
//        }
//    };
//
//
//    /**
//     * 创建LCN代理连接池
//     *
//     * @param connection
//     * @param txTransactionLocal
//     * @return
//     */
//    protected abstract T createLcnConnection(T connection, TxTransactionLocal txTransactionLocal);
//
//    /**
//     * 获取数据库连接对象
//     *
//     * @return
//     * @throws SQLException
//     */
//    public abstract Connection getConnection() throws SQLException;
//
//    /**
//     * 获取数据库连接对象
//     *
//     * @param username
//     * @param password
//     * @return
//     * @throws SQLException
//     */
//    public abstract Connection getConnection(String username, String password) throws SQLException;
//
//    public DataSource getDataSource() {
//        return dataSource;
//    }
//
//    public void setDataSource(DataSource dataSource) {
//        this.dataSource = dataSource;
//    }
//
//    public void setMaxCount(int maxCount) {
//        this.maxCount = maxCount;
//    }
//
//    public void setRequestTimeOut(int requestTimeOut) {
//        this.requestTimeOut = requestTimeOut;
//    }
//
//    /**
//     * default
//     **/
//    @Override
//    public <T> T unwrap(Class<T> iface) throws SQLException {
//        return getDataSource().unwrap(iface);
//    }
//
//    @Override
//    public boolean isWrapperFor(Class<?> iface) throws SQLException {
//        return getDataSource().isWrapperFor(iface);
//    }
//
//    @Override
//    public PrintWriter getLogWriter() throws SQLException {
//        return getDataSource().getLogWriter();
//    }
//
//    @Override
//    public void setLogWriter(PrintWriter out) throws SQLException {
//        getDataSource().setLogWriter(out);
//    }
//
//    @Override
//    public void setLoginTimeout(int seconds) throws SQLException {
//        getDataSource().setLoginTimeout(seconds);
//    }
//
//    @Override
//    public int getLoginTimeout() throws SQLException {
//        return getDataSource().getLoginTimeout();
//    }
//
//    @Override
//    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
//        return getDataSource().getParentLogger();
//    }
//}
